/*
    This file is part of Emu.

    Emu is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Emu is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Emu.  If not, see <http://www.gnu.org/licenses/>. */
#include <QDir>
#include <QFile>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QMessageBox>
#include <QVBoxLayout>

#include "esessioneditor.h"
#include "eprofilereader.h"
#include "eprofilewriter.h"
#include "eprofilemanager.h"

EProfileManager::EProfileManager(QWidget *parent)
    : QDialog(parent)
{
    QHBoxLayout *buttonLayout = new QHBoxLayout;
    QVBoxLayout *layout = new QVBoxLayout;
    int i;
    QStringList headerLabels = QStringList() << "Name" << "Address" << "Port";
    _profileTree = new QTreeWidget;
    _profileTree->setHeaderLabels(headerLabels);
    /* QTreeWidget sometimes gets confused and thinks that entries are a lot
       longer than they really are. There are no benefits to showing this
       scrollbar, but it does look ugly and silly given the small screen space
       needed for showing the data.
       Disable this scrollbar. */
    _profileTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    /* Make stuff resize as much as it needs to, in case some of the entries are
       a bit big. */
    for (i = 0;i < headerLabels.size();i++)
        _profileTree->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);

    initProfileTree();

    QPushButton *addButton = new QPushButton(QIcon(":/icons/add_item.png"),
            tr("Add"));
    _editButton = new QPushButton(QIcon(":/icons/edit_item.png"), tr("Edit"));
    _deleteButton = new QPushButton(QIcon(":/icons/delete_item.png"),
            tr("Delete"));

    _buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok |
            QDialogButtonBox::Cancel);

    buttonLayout->addWidget(addButton);
    buttonLayout->addWidget(_editButton);
    buttonLayout->addWidget(_deleteButton);

    layout->addWidget(_profileTree);
    layout->addLayout(buttonLayout);
    layout->addWidget(_buttonBox);

    toggleEditingButtons(_profileTree->topLevelItemCount() != 0);

    connect(addButton, SIGNAL(clicked()), this, SLOT(addProfile()));
    connect(_editButton, SIGNAL(clicked()), this, SLOT(editProfile()));
    connect(_deleteButton, SIGNAL(clicked()), this, SLOT(deleteProfile()));
    connect(_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

    setLayout(layout);
    setWindowTitle(tr("Load Emu Profile"));
}

void EProfileManager::initProfileTree()
{
    int i;
    QString basepath = QDir::homePath() + "/.config/emu/";
    QDir d(basepath);
    d.setNameFilters(QStringList() << "*.epr");

    EProfileReader reader;
    QStringList allProfiles = d.entryList();
    QList <QStringList> validProfiles;

    /* Find the name, host, and port specified in each profile. */
    for (i = 0;i < allProfiles.size();i++) {
        QString err;
        EProfile *prefs = reader.readPrefs(basepath + allProfiles.at(i), &err);
        if (err.isEmpty() == false) {
            delete prefs;
            continue;
        }

        validProfiles.append(QStringList() <<
                prefs->hostName() <<
                prefs->hostAddress() <<
                prefs->hostPort() <<
                basepath + allProfiles.at(i));
    }

    /* Put all the entries in the tree. */
    for (i = 0;i < validProfiles.size();i++) {
        QStringList entry = validProfiles.at(i);
        QTreeWidgetItem *item = new QTreeWidgetItem;
        item->setText(0, entry.at(0));
        item->setText(1, entry.at(1));
        item->setText(2, entry.at(2));
        item->setText(3, entry.at(3));
        _profileTree->addTopLevelItem(item);
    }

    if (i >= 1)
        _profileTree->setCurrentItem(_profileTree->topLevelItem(0));
}

EProfile *EProfileManager::selectedPrefs()
{
    EProfileReader reader;
    QString err;
    return reader.readPrefs(_profileTree->currentItem()->text(3), &err);
}

void EProfileManager::addProfile()
{
    EProfile *prefs = new EProfile;

    ESessionEditor editor(prefs, this);
    if (editor.exec() == QDialog::Accepted) {
        EProfileWriter w;
        QString err;
        w.savePrefs(prefs, &err);
        if (err.isEmpty() == false) {
            QMessageBox::warning(0, tr("Emu"), err, QMessageBox::Ok);
            return;
        }
        QTreeWidgetItem *newItem = new QTreeWidgetItem;

        /* Add the item to the tree manually. */
        newItem->setText(0, prefs->hostName());
        newItem->setText(1, prefs->hostAddress());
        newItem->setText(2, prefs->hostPort());
        newItem->setText(3, prefs->profilePath());
        _profileTree->addTopLevelItem(newItem);
        if (_profileTree->topLevelItemCount() == 1) {
            _profileTree->setCurrentItem(newItem);
            toggleEditingButtons(true);
        }
    }
}

void EProfileManager::editProfile()
{
    EProfileReader r;
    QString err;

    EProfile *profile = r.readPrefs(_profileTree->currentItem()->text(3), &err);
    ESessionEditor editor(profile, this);

    if (editor.exec() == QDialog::Accepted) {
        EProfileWriter w;
        w.savePrefs(profile, &err);
        if (!err.isEmpty())
            QMessageBox::warning(0, tr("Emu"), tr("Failed to save profile."),
                                 QMessageBox::Ok);
        else {
            /* Update the item text in case these changed. Otherwise, the user
               may think (and rightly so) that the changes didn't happen. */
            QTreeWidgetItem *current = _profileTree->currentItem();
            current->setText(0, profile->hostName());
            current->setText(1, profile->hostAddress());
            current->setText(2, profile->hostPort());
        }
    }

    delete profile;
}

void EProfileManager::deleteProfile()
{
    QMessageBox::StandardButton closePrompt = QMessageBox::warning(this,
            tr("Emu"),
            tr("Are you sure you want to delete the profile for '%1'?")
            .arg(_profileTree->currentItem()->text(0)),
            QMessageBox::Yes | QMessageBox::No);

    if (closePrompt == QMessageBox::No)
        return;

    QFile::remove(_profileTree->currentItem()->text(3));
    delete _profileTree->currentItem();

    /* If nothing to edit or delete, disable those. */
    if (_profileTree->topLevelItemCount() == 0)
        toggleEditingButtons(false);
}

void EProfileManager::toggleEditingButtons(bool enable)
{
    _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enable);
    _editButton->setEnabled(enable);
    _deleteButton->setEnabled(enable);
}
